package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.sun.xml.internal.xsom.impl.scd.Iterators;
import com.tanhua.common.pojo.Dynamic;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.service.PicUploadService;
import com.tanhua.common.utils.RelativeDateFormat;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.PageResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.server.api.SelectFriends;
import com.tanhua.dubbo.server.enums.CommentType;
import com.tanhua.dubbo.server.enums.Ttype;
import com.tanhua.dubbo.server.pojo.Comment;
import com.tanhua.dubbo.server.pojo.Publish;
import com.tanhua.dubbo.server.vo.PageInfo;
import com.tanhua.dubbo.server.vo.CommentVo;
import com.tanhua.server.vo.QuanZiVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.aggregation.VariableOperators;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class QuanZiService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private UserInfoService userInfoService;

    @Reference(version = "1")
    private SelectFriends selectFriends;

    @Autowired
    private PicUploadService picUploadService;

    /**
     * 查询好友动态
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findQuanZiVo(Integer page, Integer pagesize) {
        //从本地线程获取user,在token拦截器中校验成功后就会把user放入UserThreadLocal中
        User user = UserThreadLocal.get();

        //dubbo远程调用获取好友部分数据
        PageInfo<Publish> publish = selectFriends.selectFriends(user.getId(), page, pagesize);
        if (publish.getRecords() == null) {
            return null;
        }

        //获取好友用户ID
        List<Publish> records = publish.getRecords();
        List<QuanZiVo> quanZiVoList = getQuanZiVos(records);
        if (quanZiVoList == null) {
            return null;
        }

       /* QuanZiVo quanZiVo;
        List<QuanZiVo>list=new ArrayList<>();
        for (int i = 0; i < records.size(); i++) {
            quanZiVo=new QuanZiVo();
            //userInfos.get(i)对象的值复制到quanZiVo中
            BeanUtils.copyProperties(userInfos.get(i),quanZiVo);

            quanZiVo.setGender(userInfos.get(i).getSex().name().toLowerCase());
            quanZiVo.setTags(StringUtils.split(userInfos.get(i).getTags(), ","));
            quanZiVo.setCommentCount(0);
            quanZiVo.setDistance("1.2公里");
            quanZiVo.setHasLiked(0);
            quanZiVo.setLikeCount(0);
            quanZiVo.setHasLoved(0); /
            quanZiVo.setLoveCount(0);
            quanZiVo.setId(publish.getRecords().get(i).getId().toHexString());
            quanZiVo.setTextContent(publish.getRecords().get(i).getText());
            quanZiVo.setImageContent(publish.getRecords().get(i).getMedias().toArray(new String[]{}));
            quanZiVo.setUserId(publish.getRecords().get(i).getUserId());
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getRecords().get(i).getCreated())));
            //添加数据
            list.add(quanZiVo);
        }*/

        //数据封装
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pagesize);
        pageResult.setItems(quanZiVoList);
        return pageResult;
    }

    //查询动态信息并封装成QuanZiVos
    private List<QuanZiVo> getQuanZiVos(List<Publish> records) {
        //获取records中所有的userId到一个新集合
        List<Object> userId = CollUtil.getFieldValues(records, "userId");
        List<UserInfo> userInfos = userInfoService.selectUserInfos(new QueryWrapper<UserInfo>().in("user_id", userId));
        if (userInfos.get(0) == null) {
            return null;
        }

        // Map<Long, UserInfo> collect = userInfos.stream().collect(Collectors.toMap(UserInfo::getUserId, Function.identity()));

        //先进行数据封装,后根据现在以封装的用户ID去对比userInfo查出来的数据的ID,以防一个好友多条动态
        List<QuanZiVo> quanZiVoList = new ArrayList<>();
        records.forEach(publishs -> {
            QuanZiVo quanZiVo = new QuanZiVo();
            quanZiVo.setId(publishs.getId().toHexString());
            quanZiVo.setTextContent(publishs.getText());
            quanZiVo.setImageContent(publishs.getMedias().toArray(new String[]{}));
            quanZiVo.setUserId(publishs.getUserId());
            quanZiVo.setCreateDate(RelativeDateFormat.format(new Date(publishs.getCreated())));

            quanZiVoList.add(quanZiVo);
        });

        //通过userid来绑定动态(说说)和用户信息的一致,解决一用户多条动态的问题
        for (QuanZiVo quanZiVo : quanZiVoList) {
            //找到对应的用户信息
            for (UserInfo userInfo : userInfos) {
                if (quanZiVo.getUserId().longValue() == userInfo.getUserId().longValue()) {
                    //调用封装用户数据的方法,将quanZiVoList集合里的每一个quanZiVo与userInfos集合里的userInfo数据进行绑定
                    fillUserInfoToQuanZiVo(userInfo, quanZiVo);
                    break;
                }
            }

        }
        return quanZiVoList;
    }


    /***
     * 用户封装方法
     * @param userInfo 用户信息
     * @param quanZiVo 封装对象
     */
    private void fillUserInfoToQuanZiVo(UserInfo userInfo, QuanZiVo quanZiVo) {
        //quanZiVo返回给前端的数据,本身是圈子里面的动态的数据
        //copyProperties()将userInfo里面除了id以外的数据全部填充到quanZiVo中
        BeanUtil.copyProperties(userInfo, quanZiVo, "id");
        quanZiVo.setGender(userInfo.getSex().name().toLowerCase());
        quanZiVo.setTags(StringUtils.split(userInfo.getTags(), ","));
        quanZiVo.setCommentCount(selectFriends.queryLikeCount(quanZiVo.getId(), CommentType.COMMENT).intValue());
        quanZiVo.setDistance("1.2公里"); //TODO 距离
        quanZiVo.setHasLiked(selectFriends.getWhetherItIsTrue(quanZiVo.getId(), UserThreadLocal.get().getId(), CommentType.LIKE) ? 1 : 0);
        quanZiVo.setLikeCount(selectFriends.queryLikeCount(quanZiVo.getId(), CommentType.LIKE).intValue());
        quanZiVo.setHasLoved(selectFriends.getWhetherItIsTrue(quanZiVo.getId(), UserThreadLocal.get().getId(), CommentType.LOVE) ? 1 : 0);
        quanZiVo.setLoveCount(selectFriends.queryLikeCount(quanZiVo.getId(), CommentType.LOVE).intValue());
    }

    /**
     * 发布动态
     *
     * @param dynamic
     * @return
     */
    public String insertPublish(Dynamic dynamic) {
        //从本地线程获取user,在token拦截器中校验成功后就会把user放入UserThreadLocal中
        User user = UserThreadLocal.get();
        //数据封装
        Publish publish = new Publish();
        publish.setUserId(user.getId());
        publish.setText(dynamic.getTextContent());
        publish.setLocationName(dynamic.getLocation());
        publish.setLatitude(dynamic.getLatitude());
        publish.setLongitude(dynamic.getLongitude());
        publish.setSeeType(1);
        //拿到图片
        MultipartFile[] imageContent = dynamic.getImageContent();
        //图片地址集合
        List<String> list = new ArrayList<>();
        //进行判断是否有图片
        if (imageContent != null) {
            for (MultipartFile multipartFile : imageContent) {
                PicUploadResult result = picUploadService.upload(multipartFile);
                list.add(result.getName());
            }
            //添加图片地址
            publish.setMedias(list);
        }
        //返回publishID
        return selectFriends.insertDynamic(publish);
    }

    /**
     * 推荐用户方法
     *
     * @param page     当前页
     * @param pageSize 每页显示多少数据
     * @return
     */
    public PageResult QueryRecommendMessage(Integer page, Integer pageSize) {
        if (pageSize == null) {
            pageSize = 10;
        }
        //直接从ThreadLocal中获取对象
        User user = UserThreadLocal.get();

        //通过dubbo查询数据并判断是否为空
        PageInfo<Publish> pageInfo = selectFriends.selectRecommend(user.getId(), page, pageSize);
        List<Publish> records = pageInfo.getRecords();
        if (CollUtil.isEmpty(records)) {
            return null;
        }
        //数据封装
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        pageResult.setItems(getQuanZiVos(records));
        return pageResult;
    }

    /**
     * 进行点赞或喜欢方法以及取消点赞喜欢方法,根据commentType和tType判断
     *
     * @param publishId
     * @param commentType
     * @return
     */
    public Long arbitrarilyComment(String publishId, CommentType commentType, Ttype tType) {
        //获得当前用户的ID
        User user = UserThreadLocal.get();
        //根据commentType进行点赞或喜欢,成功返回true
        if (tType == Ttype.INSERT) {
            Boolean aBoolean = selectFriends.likeLoveComment(user.getId(), publishId, commentType, null);
            if (!aBoolean) {
                return null;
            }
        } else {
            Boolean disLikeComment = selectFriends.disLikeComment(user.getId(), publishId, commentType, null);
            if (!disLikeComment) {
                return null;
            }
        }

        //获取点赞数或者喜欢数并返回
        return selectFriends.queryLikeCount(publishId, commentType);

    }

    /**
     * 根据动态ID(publishId)查询该用户动态信息
     *
     * @param publishId
     * @return
     */
    public QuanZiVo oneComment(String publishId) {
        List<QuanZiVo> quanZiVos = null;
        try {
            Publish publish = selectFriends.selectID(publishId);
            List<Publish> list = new ArrayList<>();
            list.add(publish);
            //调用数据封装方法
            quanZiVos = getQuanZiVos(list);
            return quanZiVos.get(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查询单条动态所有评论
     *
     * @param publishId
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findComments(String publishId, Integer page, Integer pagesize) {
        //设置类型为评论
        CommentType comment = CommentType.COMMENT;
        //去MongoDB查询评论信息
        List<Comment> list = selectFriends.selectComments(publishId, page, pagesize, comment);

        //将list中的userid保存到一个新数组中
        List<Object> userId = CollUtil.getFieldValues(list, "userId");


        //根据userid去mysql中进行查询
        List<UserInfo> userInfo = userInfoService.selectUserInfos(new QueryWrapper<UserInfo>().in("user_id", userId));
        Map<Long, UserInfo> collect = userInfo.stream().collect(Collectors.toMap(UserInfo::getUserId, Function.identity()));

        //数据封装
        List<CommentVo> commentVos = new ArrayList<>();
        CommentVo commentVo;
        for (Comment comment1 : list) {
            commentVo = new CommentVo();

            //是否点赞
            commentVo.setHasLiked(selectFriends.getWhetherItIsTrue(comment1.getId().toHexString(), UserThreadLocal.get().getId(), CommentType.LIKE) ? 1 : 0);
            //评论内容
            commentVo.setContent(comment1.getContent());
            //评论时间,转换后的
            commentVo.setCreateDate(DateUtil.format(new Date(comment1.getCreated()), "HH:mm"));
            //评论ID
            commentVo.setId(comment1.getId().toHexString());
            //点赞数
            commentVo.setLikeCount(selectFriends.queryLikeCount(commentVo.getId(), CommentType.LIKE).intValue());
            //头像
            commentVo.setAvatar(collect.get(comment1.getUserId()).getLogo());
            //昵称
            commentVo.setNickname(collect.get(comment1.getUserId()).getNickName());

            commentVos.add(commentVo);


        }

        //根据时间进行降序排序并进行封装返回
        commentVos.sort((o1, o2) -> (int) (DateUtil.parse(o2.getCreateDate(), "HH:mm").getTime() - DateUtil.parse(o1.getCreateDate(), "HH:mm").getTime()));
        PageResult pageResult = new PageResult();
        pageResult.setCounts(100);
        pageResult.setPage(page);
        pageResult.setPagesize(pagesize);
        pageResult.setPages(1);
        pageResult.setItems(commentVos);
        return pageResult;
    }

    /**
     * 对动态评论
     *
     * @param movementId
     * @param comment
     * @return
     */
    public ResponseEntity<?> commentsSubmit(String movementId, String comment) {
        Boolean aBoolean = selectFriends.setComment(UserThreadLocal.get().getId(), movementId, CommentType.COMMENT, comment, 1);
        if (!aBoolean) {
            return ResponseEntity.ok("评论失败!");
        }
        return ResponseEntity.ok(null);
    }
}


